#include "bsp_eth.h"



/* BSP-ETH */
/**
 * RMII_MDIO : PA2 - AF11
 * RMM_MDC : PC1 - AF11
 * RMII_TX_EN : PB11 - AF11
 * RMII_TXD0 : PB12 - AF11
 * RMII_TXD1 : PB13 - AF11
 * RMII_RXD0 : PC4 - AF11
 * RMII_RXD1 : PC5 - AF11
 * RMII_CRS_DV : PA7 : AF11
 * RMII_REF_CLK : PA1 : AF11
 * 
 */


/* static var */


static ETH_HandleTypeDef eth_handle;
static __AT_RAM_SRAM3(0x30040000) ETH_DMADescTypeDef eth_dma_tx_tbl[ETH_TX_DESC_CNT];
static __AT_RAM_SRAM3(0x30040060) ETH_DMADescTypeDef eth_dma_rx_tbl[ETH_RX_DESC_CNT];
static __AT_RAM_SRAM3(0x30040200) uint8_t eth_rx_buff[ETH_RX_DESC_CNT][ETH_MAX_PACKET_SIZE];
static uint8_t eth_mac[6] = { 0 };


/* static func */

//ETH中断服务函数
void ETH_IRQHandler(void)
{
    HAL_ETH_IRQHandler(&eth_handle);
}


/* export func */

/**
 * @brief 初始化
 * 
 */
void bsp_eth_init(void)
{
    GPIO_InitTypeDef GPIO_InitStruct;

    __HAL_RCC_GPIOA_CLK_ENABLE();
    __HAL_RCC_GPIOB_CLK_ENABLE();
    __HAL_RCC_GPIOC_CLK_ENABLE();

    /* RMII_REF_CLK : PA1 : AF11 */
    /* RMII_MDIO : PA2 - AF11 */
    /* RMII_CRS_DV : PA7 : AF11 */
    GPIO_InitStruct.Pin = GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7;
    GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
    GPIO_InitStruct.Pull = GPIO_NOPULL;
    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
    GPIO_InitStruct.Alternate = GPIO_AF11_ETH;
    HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);

    /* RMII_TX_EN : PB11 - AF11 */
    /* RMII_TXD0 : PB12 - AF11 */
    /* RMII_TXD1 : PB13 - AF11 */
    GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13;
    HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

    /* RMM_MDC : PC1 - AF11 */
    /* RMII_RXD0 : PC4 - AF11 */
    /* RMII_RXD1 : PC5 - AF11 */
    GPIO_InitStruct.Pin = GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5;
    HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);

    /* eth */
    __HAL_RCC_ETH1MAC_CLK_ENABLE();
    __HAL_RCC_ETH1TX_CLK_ENABLE();
    __HAL_RCC_ETH1RX_CLK_ENABLE();

    memset(&eth_handle, 0x00, sizeof(ETH_HandleTypeDef));

    eth_handle.Instance = ETH;
    eth_handle.Init.MACAddr = eth_mac;
    eth_handle.Init.MediaInterface = HAL_ETH_RMII_MODE;
    eth_handle.Init.RxDesc = eth_dma_rx_tbl;
    eth_handle.Init.TxDesc = eth_dma_tx_tbl;
    eth_handle.Init.RxBuffLen = ETH_MAX_PACKET_SIZE;
    HAL_ETH_Init(&eth_handle);
    HAL_ETH_SetMDIOClockRange(&eth_handle);


    printf("eth_dma_tx_tbl addr = 0x%08X\r\n", (uint32_t)eth_dma_tx_tbl);
    printf("eth_dma_rx_tbl addr = 0x%08X\r\n", (uint32_t)eth_dma_rx_tbl);
    printf("eth_rx_buff addr = 0x%08X\r\n", (uint32_t)eth_rx_buff);

    memset(eth_dma_tx_tbl, 0x00, sizeof(ETH_DMADescTypeDef)*ETH_TX_DESC_CNT);
    memset(eth_dma_rx_tbl, 0x00, sizeof(ETH_DMADescTypeDef)*ETH_RX_DESC_CNT);
    memset(eth_rx_buff, 0x00, ETH_RX_DESC_CNT * ETH_MAX_PACKET_SIZE);
}

/**
 * @brief 去初始化
 * 
 */
void bsp_eth_deinit(void)
{
    __HAL_RCC_ETH1MAC_CLK_DISABLE();
    __HAL_RCC_ETH1TX_CLK_DISABLE();
    __HAL_RCC_ETH1RX_CLK_DISABLE();

    HAL_GPIO_DeInit(GPIOA, GPIO_PIN_1 | GPIO_PIN_2 | GPIO_PIN_7);
    HAL_GPIO_DeInit(GPIOB, GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13);
    HAL_GPIO_DeInit(GPIOC, GPIO_PIN_1 | GPIO_PIN_4 | GPIO_PIN_5);
}

/**
 * @brief 获取设备句柄
 * 
 * @return ETH_HandleTypeDef* 
 */
ETH_HandleTypeDef *bsp_eth_get_handle(void)
{
    return &eth_handle;
}

/**
 * @brief 设置MAC地址
 * 
 * @param mac 
 */
void bsp_eth_set_mac(uint8_t *mac)
{
    uint8_t i;
    
    for (i=0; i<6; i++)
    {
        eth_mac[i] = mac[i];
    }
}

/**
 * @brief 读设备寄存器
 * 
 * @param addr 设备地址
 * @param reg 寄存器地址
 * @param value 数据内容
 * @return uint8_t 
 */
uint8_t bsp_eth_read_phy_reg(uint32_t addr, uint32_t reg, uint32_t *value)
{
    HAL_StatusTypeDef sta;

    sta = HAL_ETH_ReadPHYRegister(&eth_handle, addr, reg, value);
    if (sta != HAL_OK)
    {
        return 1;
    }
    return 0;
}

/**
 * @brief 写设备寄存器
 * 
 * @param addr 设备地址
 * @param reg 寄存器地址
 * @param value 数据内容
 * @return uint8_t 
 */
uint8_t bsp_eth_write_phy_reg(uint32_t addr, uint32_t reg, uint32_t value)
{
    HAL_StatusTypeDef sta;

    sta = HAL_ETH_WritePHYRegister(&eth_handle, addr, reg, value);
    if (sta != HAL_OK)
    {
        return 1;
    }
    return 0;
}




